﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Data.SqlClient;

namespace TercerPlaneta.Lib
{
    /// <summary>
    /// Esta clase contiene los métodos de encriptación para poder 
    /// guardar datos de usuario y clave en la configuracion, entre otros usos
    /// </summary>
    public sealed class StringConfig
    {

        // Aca guarda... lo que no se debe mostrar ;O)
        // Ojo, no modificar los valores
        static private byte[] lenghtList = Encoding.Default.GetBytes(new char[] { 'l', 'a', 'T', 'V', '5', 'S', 'E', 'd', 'e', 't', 'u', 'z', 's', 'u', 'e', 'ñ', 'o', 's', 'e', 's', 't', '0', 'a', 'c', 'á', 'E', 'A', 'E', 'A', 'P', 'e', 'E' });
        static private byte[] lenghtArray = Encoding.Default.GetBytes(new char[] { '%', '#', 'T', 'ñ', '8', ']', 'V', '', 'e', 'X', '+', 'b', '!', '†', '0', 'è' });

        // static class
        private StringConfig()
        {
        }

        // public methods

        // Encriptar los datos y retornar un string base64-encoded
        public static string ToConfig(string dato)
        {

            SymmetricAlgorithm saEnc;

            // Aqui se guardara el resultado 
            string resultado = "";

            // Convierte el dato string a un array de Bytes 
            byte[] dataorg = Encoding.Default.GetBytes(dato);

            // Crea el algoritmo y indica la clave y el array de inicialización
            saEnc = SymmetricAlgorithm.Create();
            saEnc.Key = lenghtList;
            saEnc.IV = lenghtArray;

            // Crea el encryptor 
            ICryptoTransform ct = saEnc.CreateEncryptor();

            // Crea streams
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);

            // Genera el dato encriptado 
            cs.Write(dataorg, 0, dataorg.Length);
            cs.FlushFinalBlock();

            // Guarda el resultado convirtiendo a base64
            resultado = "|" + Convert.ToBase64String(ms.ToArray());

            return resultado;
        }

        // Desencriptar los datos, recibiendo un string base64-encoded encriptado.
        // NOTA: puede recibir un string no encriptado, en ese caso retorna el mismo
        public static string ToString(string dato)
        {
            if (!dato.StartsWith("|"))
                return dato;

            // variable donde guardar resultado 
            string result = "";

            // Convierte texto encriptado base64 a byte[]
            byte[] textoEncriptado = Convert.FromBase64String(dato.Substring(1));

            // Crea algoritmo de encriptación, indica clave y array de inicialización 
            SymmetricAlgorithm saDEnc = SymmetricAlgorithm.Create();
            saDEnc.Key = lenghtList;
            saDEnc.IV = lenghtArray;

            // Crea streams, y decryptor
            MemoryStream ms = new MemoryStream(textoEncriptado);
            ICryptoTransform cto = saDEnc.CreateDecryptor(saDEnc.Key, saDEnc.IV);
            MemoryStream mso = new MemoryStream();
            CryptoStream cso = new CryptoStream(mso, cto, CryptoStreamMode.Write);

            // Genera el dato desencriptado 
            cso.Write(ms.ToArray(), 0, ms.ToArray().Length);
            cso.FlushFinalBlock();

            // Convierte a string 
            result = Encoding.Default.GetString(mso.ToArray());

            // Devuelve dato desencriptado 
            return result;
        }

    }
}
